#ifndef __M_LOOP_H__
#define __M_LOOP_H__

#include "util.hpp"
#include "buffer.hpp"
#include <vector>
#include <atomic>
#include <mutex>
#include <thread>
#include <condition_variable>
#include <functional>

namespace cl{
/**
 * @brief AsyncLooper 类用于异步的将任务推送到缓冲区并在后台线程中处理任务。
 * 
 * 该类通过创建一个工作线程并使用条件变量来异步处理任务。用户可以通过'push'方法将任务添加到队列，
 * 工作线程会从队列中获取任务并执行回调函数进行处理。任务处理完成后，缓冲区会被重置，等待新的任务。
 */
class AsyncLooper{
public:
    using Functor = std::function<void(Buffer &buffer)>;
    using ptr = std::shared_ptr<AsyncLooper>;
    
    AsyncLooper(const Functor& cb) 
        : _looper_callback(cb), _running(true)
        , _thread(std::thread(&AsyncLooper::worker_loop, this)) {}


    ~AsyncLooper(){ stop(); }

    // 停止异步处理器
    void stop(){
        _running = false;       
        _pop_cond.notify_all(); // 通知所有等待的线程
        _thread.join();         // 等待工作线程结束
    }

    // 向任务队列中推送消息
    void push(const std::string &msg){
        if(_running == false) return;   // 如果不在运行，直接返回

        {
            std::unique_lock<std::mutex> lock(_mutex);
            // 等待直到缓冲区有足够空间来写入新消息
            _push_cond.wait(lock, [&]{ return _tasks_push.writeAbleSize() >= msg.size(); });
            _tasks_push.push(msg.c_str(), msg.size());  // 将消息写入缓冲区
            // _pop_cond.notify_one();
        }
        _pop_cond.notify_all(); // 通知工作线程有新任务
    }

private:
    // 工作线程循环
    void worker_loop(){
        while(true){
            {
                std::unique_lock<std::mutex> lock(_mutex);
                // 如果运行标志为false且任务队列为空，退出循环
                if(_running == false && _tasks_push.empty()) { break; }
                // 等待直到有任务可处理或已请求停止
                _pop_cond.wait(lock, [&]{ return !_tasks_push.empty() || !_running; });
                _tasks_push.swap(_tasks_pop);   // 交换任务队列
            }
            _push_cond.notify_all();        // 通知处理任务
            _looper_callback(_tasks_pop);   // 执行回调函数处理任务
            _tasks_pop.reset();             // 重置已处理任务的缓冲区
        }
        return;
    }

private:
    std::mutex _mutex;  // 互斥锁
    Buffer _tasks_pop;  // 任务弹出缓冲区
    Buffer _tasks_push; // 任务推送缓冲区
    std::thread _thread;// 工作线程
    Functor _looper_callback;   // 回调函数
    std::atomic<bool> _running; // 运行状态
    std::condition_variable _push_cond; // 用于推送条件变量
    std::condition_variable _pop_cond;  // 用于弹出条件变量
}; // class AsyncLooper
}
#endif